<--- %%NOBANNER%% --> dequote.sas
 BackForward
/* %put %dequote(%bquote(this is a 'test".'));  */
%macro dequote(string);
%local _unqtstr_;
%let _unqtstr_=&string;
%if ((%index(%bquote(&string), %str(%'))) and (%index(%bquote(&string), %str(%"))) and 
    (%index(%bquote(&string), %str(%')) lt %index(%bquote(&string), %str(%")))) or 
    ((not %index(%bquote(&string), %str(%"))) and %index(%bquote(&string), %str(%'))) %then %do;
   %if (%index(%bquote(&string), %str(%')) ge 2) %then 
      %let _unqtstr_=%bquote(%substr(%bquote(&string), 1, 
      %eval(%index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(&string))))), %str(%'))-1))%substr(%bquote(&string), 
      %eval(%index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(&string))))), %str(%'))+1), 
      %eval(%length(%bquote(&string))-%index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(&string))))), %str(%')))));
   %else %let _unqtstr_=%bquote(%substr(%bquote(&string), 
   %eval(%index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(&string))))), %str(%'))+1), 
   %eval(%length(%bquote(&string))-%index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(&string))))), %str(%')))));
   %if (%index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(%sysfunc(reverse(%bquote(&_unqtstr_)))))))), %str(%')) ge 2) %then 
      %let _unqtstr_=%bquote(%sysfunc(reverse(%bquote(%substr(%bquote(%sysfunc(reverse(%bquote(&_unqtstr_)))), 
      1, %eval(%index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(%sysfunc(reverse(%bquote(&_unqtstr_)))))))), 
      %str(%'))-1))%substr(%bquote(%sysfunc(reverse(%bquote(&_unqtstr_)))), 
      %eval(%index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(%sysfunc(reverse(%bquote(&_unqtstr_)))))))), 
      %str(%'))+1), %eval(%length(%bquote(%sysfunc(reverse(%bquote(&_unqtstr_)))))-
      %index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(%sysfunc(reverse(%bquote(&_unqtstr_)))))))), %str(%'))))))));
   %else %let _unqtstr_=%bquote(%sysfunc(reverse(%bquote(%substr(%bquote(%sysfunc(reverse(%bquote(&_unqtstr_)))), 
   %eval(%index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(%sysfunc(reverse(%bquote(&_unqtstr_)))))))), 
   %str(%'))+1), %eval(%length(%bquote(%sysfunc(reverse(%bquote(&_unqtstr_)))))-
   %index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(%sysfunc(reverse(%bquote(&_unqtstr_)))))))), %str(%'))))))));
%end;
%else %if ((%index(%bquote(&string), %str(%'))) and (%index(%bquote(&string), %str(%"))) and 
    (%index(%bquote(&string), %str(%")) lt %index(%bquote(&string), %str(%')))) or 
    ((not %index(%bquote(&string), %str(%'))) and %index(%bquote(&string), %str(%"))) %then %do;
   %if (%index(%bquote(&string), %str(%")) ge 2) %then 
      %let _unqtstr_=%bquote(%substr(%bquote(&string), 1, 
      %eval(%index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(&string))))), %str(%"))-1))%substr(%bquote(&string), 
      %eval(%index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(&string))))), %str(%"))+1), 
      %eval(%length(%bquote(&string))-%index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(&string))))), %str(%")))));
   %else %let _unqtstr_=%bquote(%substr(%bquote(&string), 
   %eval(%index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(&string))))), %str(%"))+1), %eval(%length(%bquote(&string))-
   %index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(&string))))), %str(%")))));
   %if (%index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(%sysfunc(reverse(%bquote(&_unqtstr_)))))))), 
      %str(%")) ge 2) %then 
      %let _unqtstr_=%bquote(%sysfunc(reverse(%bquote(%substr(%bquote(%sysfunc(reverse(%bquote(&_unqtstr_)))), 
      1, %eval(%index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(%sysfunc(reverse(%bquote(&_unqtstr_)))))))), 
      %str(%"))-1))%substr(%bquote(%sysfunc(reverse(%bquote(&_unqtstr_)))), 
      %eval(%index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(%sysfunc(reverse(%bquote(&_unqtstr_)))))))), 
      %str(%"))+1), %eval(%length(%bquote(%sysfunc(reverse(%bquote(&_unqtstr_)))))-
      %index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(%sysfunc(reverse(%bquote(&_unqtstr_)))))))), %str(%"))))))));
   %else %let _unqtstr_=%bquote(%sysfunc(reverse(%bquote(%substr(%bquote(%sysfunc(reverse(%bquote(&_unqtstr_)))), 
   %eval(%index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(%sysfunc(reverse(%bquote(&_unqtstr_)))))))), 
   %str(%"))+1), %eval(%length(%bquote(%sysfunc(reverse(%bquote(&_unqtstr_)))))-
   %index(%BQUOTE(%trim(%BQUOTE(%left(%BQUOTE(%sysfunc(reverse(%bquote(&_unqtstr_)))))))), %str(%"))))))));
%end; &_unqtstr_ 
%mend dequote;